; for AutoCAD 2021 later
; file encoding: utf-8
(defun string_split (str key / regex-obj result-list pattern) 
  (setq pattern (strcat "([^" 
                        (vl-string-right-trim "\\" (vl-princ-to-string key))
                        "]+)"
                )
  )
  (setq regex-obj (vlax-create-object "vbscript.regexp"))
  (vlax-put-property regex-obj 'Global 1)
  (vlax-put-property regex-obj 'Pattern pattern)
  (vlax-for match (vlax-invoke regex-obj 'Execute str) 
    (setq result-list (cons (vla-get-Value match) result-list))
  )
  (vlax-release-object regex-obj)
  (reverse result-list)
)


;; 字符串合并函数（改进版）
;; 用法：(string_join (list "a" "b" "c") "+") -> "a+b+c"
(defun string_join (lst key / str) 
  (setq str "") ; 初始化空字符串
  (if lst  ; 避免空列表崩溃
    (progn 
      (setq str (car lst)) ; 第一个元素直接赋值
      (foreach x (cdr lst)  ; 从第二个元素开始遍历
        (setq str (strcat str key x))
      )
    )
  )
  str ; 返回合并后的字符串
)

(defun list_to_string (myList key / line_data) 
  (setq line_data '()) ; 初始化空列表
  (foreach item myList 
    (setq line_data ; 改用cons提升性能
                    (cons 
                      (if (eq (type item) 'STRING)  ; 修复类型检查（'STRING非'STR）
                        item
                        (vl-princ-to-string item) ; 支持所有类型转字符串
                      )
                      line_data
                    )
    )
  )
  (setq line_data (reverse line_data)) ; 反转恢复顺序
  (string_join line_data key)
)


(defun string_to_float (str / cleaned strlst dotcnt tmp result) 
  ;; 清理非法字符并规范化格式
  (setq cleaned (vl-string-trim " " str) ; 去除首尾空格
        cleaned (vl-list->string  ; 过滤非数字字符
                                 (vl-remove-if-not 
                                   '(lambda (c) 
                                      (or (<= 48 c 57)  ; 0-9
                                          (= c 46) ; .
                                          (= c 44) ; ,
                                          (= c 101) ; e
                                          (= c 69) ; E
                                          (= c 45) ; -
                                      )
                                    )
                                   (vl-string->list cleaned)
                                 )
                ) ;; 处理逗号小数分隔符
        cleaned (vl-string-subst "." "," cleaned) ;; 处理多余符号
        strlst  (string_split cleaned "eE")
        dotcnt  0
  )

  ;; 验证数字有效性
  (cond 
    ((= cleaned "") nil) ; 空字符串
    ((> (length strlst) 2) nil) ; 多个指数符号
    (T
     (setq tmp (car strlst))
     ;; 检查小数点数量
     (foreach c (vl-string->list tmp) 
       (if (= c 46) (setq dotcnt (1+ dotcnt)))
     )
     (if (> dotcnt 1) 
       nil ; 多个小数点
       (progn 
         ;; 尝试转换
         (if 
           (vl-catch-all-error-p 
             (setq result (vl-catch-all-apply 'atof (list cleaned)))
           )
           nil ; 转换失败
           result
         )
       )
     )
    )
  )
)

(defun float_equal (a b epsilon) 
  (< (abs (- a b)) epsilon)
)

(defun mvs_print (myList) 
  (foreach item myList 
    (princ 
      (if (eq (type item) 'STR) 
        item
        (vl-princ-to-string item)
      )
    )
  )
  (princ "\n")
)

;; 文件写入行函数（修复性能问题和类型检查）
(defun mvs_file_write_line (myList file key / line_data) 
  (setq line_data '()) ; 初始化空列表
  (foreach item myList 
    (setq line_data ; 改用cons提升性能
                    (cons 
                      (if (eq (type item) 'STRING)  ; 修复类型检查（'STRING非'STR）
                        item
                        (vl-princ-to-string item) ; 支持所有类型转字符串
                      )
                      line_data
                    )
    )
  )
  (setq line_data (reverse line_data)) ; 反转恢复顺序
  (princ (list_to_string myList key) file) ; 写入合并字符串
  (princ "\n" file) ; 写入换行符
  T ; 显式返回成功标识
)

(defun get_two_numbers (msg default_value / str num_list num1 num2) 
  ;; 获取用户输入并分割为列表（支持多个空格/制表符分隔）
  (setq str (getstring 
              (strcat "\n" msg " <当前值:" (vl-princ-to-string default_value) ">: ")
            )
  )
  (if (= str "") (setq str (vl-princ-to-string default_value)))

  (setq num_list (string_split (vl-string-trim " " str) " ")) ; 使用自定义string_split函数

  ;; 定义辅助函数：检查字符串是否能转为有效数字
  (defun valid_number? (s) 
    (and (distof s) T)
  )

  ;; 处理分割后的列表
  (cond 
    ;; 情况1：输入两个有效数字
    ((and (= (length num_list) 2) 
          (valid_number? (car num_list))
          (valid_number? (cadr num_list))
     )
     (list (distof (car num_list)) (distof (cadr num_list)))
    )

    ;; 情况2：输入一个有效数字
    ((and (= (length num_list) 1) 
          (valid_number? (car num_list))
     )
     (list (distof (car num_list)) (distof (car num_list)))
    )

    ;; 其他情况：返回默认值
    (T
     (list default_value default_value)
    )
  )
)

;; 创建或获取命名字典
(defun create_dict (dict_name / dict dname) 
  (setq dname (cdr (assoc -1 (dictsearch (namedobjdict) dict_name))))
  (if (not dname) 
    (progn 
      (setq dict '((0 . "DICTIONARY") (100 . "AcDbDictionary")))
      (if (setq dname (entmakex dict)) 
        (progn 
          (dictadd (namedobjdict) dict_name dname)
          ; (mvs_print (list "\n创建字典" dict_name))
          dname ; 返回新建字典的实体名
        )
        (princ "\n错误: 字典创建失败!")
      )
    )
    (progn 
      ; (princ "\n词典已存在")
      (mvs_print (list "\n词典" dict_name "已存在!"))
      dname ; 返回现有字典实体名
    )
  )
)

(defun remove_dict (dict_name) 
  (dictremove (namedobjdict) dict_name) ; 安全移除旧键
)

(defun remove_dict_data (dict_name key / dname) 
  (setq dname (cdr (assoc -1 (dictsearch (namedobjdict) dict_name))))
  (if dname 
    (dictremove dname key) ; 安全移除旧键
  )
)

;; 设置字典键值（支持多数据类型）
(defun set_dict_data (dict_name key value / dname xlist xname) 
  (setq dname (cdr (assoc -1 (dictsearch (namedobjdict) dict_name))))
  (if dname 
    (progn 
      (dictremove dname key) ; 安全移除旧键

      ;; 根据数据类型选择组码
      (cond 
        ((= (type value) 'STR)
         (setq xlist (list '(0 . "XRECORD") 
                           '(100 . "AcDbXrecord")
                           (cons 300 key)
                           (cons 1 value)
                     )
         )
        )
        ((= (type value) 'INT)
         (setq xlist (list '(0 . "XRECORD") 
                           '(100 . "AcDbXrecord")
                           (cons 300 key)
                           (cons 70 value)
                     )
         )
        )
        ((= (type value) 'REAL)
         (setq xlist (list '(0 . "XRECORD") 
                           '(100 . "AcDbXrecord")
                           (cons 300 key)
                           (cons 40 value)
                     )
         )
        )
        (T
         (setq xlist (list '(0 . "XRECORD") 
                           '(100 . "AcDbXrecord")
                           (cons 300 key)
                           (cons 1 (vl-princ-to-string value))
                     )
         )
        )
      )

      (if (setq xname (entmakex xlist)) 
        (progn 
          (dictadd dname key xname)
          T ; 返回成功标志
        )
        (princ "\n错误: XRecord 创建失败!")
      )
    )
    (princ "\n错误: 字典不存在!")
  )
)

;; 获取字典数据（自动识别类型）
(defun get_dict_data (dict_name key / dname entry) 
  (setq dname (cdr (assoc -1 (dictsearch (namedobjdict) dict_name))))
  (if dname 
    (if (setq entry (dictsearch dname key)) 
      (cond 
        ((assoc 1 entry) (cdr (assoc 1 entry))) ; 字符串
        ((assoc 70 entry) (cdr (assoc 70 entry))) ; 整数
        ((assoc 40 entry) (cdr (assoc 40 entry))) ; 浮点数
        (T nil)
      )
      (progn 
        ; (princ (strcat "\n警告: 键 '" (vl-princ-to-string key) "' 不存在!"))
        nil
      )
    )
    nil
  )
)

(defun count_dict (dict_name / entry count) 
  (setq count 0)
  (setq dname (cdr (assoc -1 (dictsearch (namedobjdict) dict_name))))
  (if dname 
    (progn 
      (setq entry (dictnext dname T)) ; 获取第一个键
      (while entry 
        (setq count (+ count 1))
        (setq entry (dictnext dname)) ; 获取下一个键
      )
    )
  )
  count
)

;; 增强版字典列表（完整显示键值对）
(defun list_dict_data (dict_name / key xrec data result) 
  (setq dname (cdr (assoc -1 (dictsearch (namedobjdict) dict_name))))
  (if dname 
    (progn 
      (setq result '())
      (setq entry (dictnext dname T)) ; 获取第一个键
      (while entry 
        ; (princ entry)
        (setq key (cdr (assoc 300 entry)))
        (setq value (cond 
                      ((assoc 1 entry) (cdr (assoc 1 entry))) ; 字符串
                      ((assoc 70 entry) (cdr (assoc 70 entry))) ; 整数
                      ((assoc 40 entry) (cdr (assoc 40 entry))) ; 浮点数
                      (T nil)
                    )
        )
        ; (mvs_print (list key " -> " value))
        (setq result (cons (cons key value) result)) ; 改用cons提升性能
        (setq entry (dictnext dname)) ; 获取下一个键
      )
      (reverse result) ; 返回排序后的键值表
    )
    nil
  )
)

  ;; 测试命令（完整验证）
; (defun c:mvs_test (/ data)
;   (setq dict_name "MVS_TEST_DICT")

;   ;; 数据写入测试
;   (set_dict_data dict_name "UserName" "李四")
;   (set_dict_data dict_name "UserAge" 30)
;   (set_dict_data dict_name "UserHeight" 180.5)
;   (set_dict_data dict_name "ActiveFlag" T) ; 布尔值转为字符串存储

;   ;; 数据读取测试
;   (princ "\n=== 单键读取测试 ===")
;   (princ (strcat "\n姓名: " (get_dict_data dict_name "UserName")))
;   (princ (strcat "\n年龄: " (itoa (get_dict_data dict_name "UserAge"))))
;   (princ (strcat "\n身高: " (rtos (get_dict_data dict_name "UserHeight") 2 1)))
;   (princ (strcat "\n激活状态: " (get_dict_data dict_name "ActiveFlag")))

;   ;; 列表功能测试
;   (princ "\n\n=== 字典列表输出 ===\n")
;   (setq datas (list_dict_data dict_name))
;   (princ datas)
;   (princ "\n")
;   (foreach item datas
;     ; (princ item)
;     ; (princ (strcat "\n键: " (car item) "  值: " (vl-princ-to-string (cadr item))))
;     (setq key   (car item)
;           value (cdr item)
;     )
;     (princ key)
;     (princ "=")
;     (princ value)
;     (princ "\n")
;   )
;   (princ)
; )

(defun get_entity_type (ename) 
  (cdr (assoc 0 (entget ename)))
)

  ;; 选择单个图元的基础函数
(defun select_entity (msg / ent) 
  (setq ent (entsel msg)) ; 基本选择操作
  (if ent 
    (car ent)
    nil
  )
)

(defun pt_to_list (pt) 
  (list (car pt) 
        (cadr pt)
        (caddr pt)
  )
)

(defun mvs_get_file (mvs_data_file / filename) 
  ;; 获取文件路径（支持预设路径或交互选择）
  ;; 参数: mvs_data_file - 预设文件路径（字符串或nil）
  ;; 返回: 文件路径字符串 或 nil（用户取消）
  (setq default_file "mvs_data.txt")
  (if mvs_data_file 
    (setq default_file mvs_data_file)
  )

  (setq filename (getfiled "保存数据到文件" default_file ; 默认文件名
                           "txt" ; 文件扩展名过滤器（空表示全部）
                           1 ; 标志位：1=允许覆盖提示
                 )
  )
  (if filename 
    filename ; 返回用户选择的路径
    (progn 
      (princ "\n操作已取消，未选择文件。")
      nil ; 明确返回nil
    )
  )
)


(defun create_layer (layername color lineweight) 
  ;; 获取用户输入
  ; (setq layername (getstring T "\n输入图层名: "))
  ; (setq color (getint "\n输入颜色索引号 (1-255): "))

  ;; 检查图层是否存在
  (if (not (tblsearch "LAYER" layername)) 
    (progn 
      ;; 构造图层数据表
      (entmake 
        (list 
          '(0 . "LAYER") ; 实体类型
          '(100 . "AcDbSymbolTableRecord") ; 必需子类标记
          '(100 . "AcDbLayerTableRecord") ; 图层表记录
          (cons 2 layername) ; 图层名
          (cons 70 0) ; 状态标志（0=默认）
          (cons 62 color) ; 颜色索引
          '(6 . "Continuous") ; 线型（默认）
          (cons 370 lineweight) ; 线宽
        )
      )
      ; (princ (strcat "\n图层 '" layername "' 创建成功。"))
    )
    (princ (strcat "\n图层 '" layername "' 已存在。"))
  )
  (princ)
)

(defun is_layer_deletable (name) 
  (and 
    (not (eq name (getvar "CLAYER"))) ; 非当前图层
    (not (member name '("0" "Defpoints"))) ; 非系统层
    (not 
      (vlax-map-collection  ; 检查是否有实体引用该图层
                           (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object)))
                           '(lambda (blk) 
                              (vlax-for obj blk (eq (vla-get-Layer obj) name))
                            )
      )
    )
  )
)

(defun force_delete_layer (name) 
  (if 
    (and 
      (tblsearch "LAYER" name)
      (is_layer_deletable name) ; 调用上述检查函数
    )
    (entdel (tblobjname "LAYER" name))
    (princ "\n无法删除该图层。")
  )
)

(defun delete_layer_ents (layName / ss) 
  ;; 1. 获取目标图层名
  ; (setq layName (getstring T "\n输入要清理的图层名: "))

  ;; 2. 创建选择集过滤该图层所有实体
  (if (setq ss (ssget "_X" (list (cons 8 layName)))) 
    (progn 
      ;; 3. 遍历并删除实体
      (repeat (setq idx (sslength ss)) 
        (entdel (ssname ss (setq idx (1- idx))))
      )
      (princ (strcat "\n已删除图层 \"" layName "\" 上的 " (itoa (sslength ss)) " 个实体。"))
    )
    (princ (strcat "\n图层 \"" layName "\" 上无实体或图层不存在。"))
  )
)

(defun set_layer_vis (layName visible / entData colorVal) 
  ;; 检查图层是否存在
  (if (setq entData (tblsearch "LAYER" layName)) 
    (progn 
      ; (princ entData)
      ;; 获取当前颜色值（组码62）
      (setq colorVal (cdr (assoc 62 entData)))

      (cond 
        ;当前不可见, 要求可见
        ((and (minusp colorVal) visible)
         (setq colorVal (abs colorVal)) ; 打开图层（颜色转正）
        )
        ; 当前可见, 要求不可见
        ((and (not (minusp colorVal)) (not visible))
         (setq colorVal (- (abs colorVal))) ; 关闭图层（颜色转负）
        )
        (T nil)
      )

      ;; 切换颜色符号（正负切换实现开关）
      ; (if (minusp colorVal)
      ;   (setq colorVal (abs colorVal)) ; 打开图层（颜色转正）
      ;   (setq colorVal (- (abs colorVal))) ; 关闭图层（颜色转负）
      ; )

      ;; 更新图层数据
      ; BUG entmod无法修改图层颜色, 原因未知
      ; (setq result (entmod
      ;                (subst
      ;                  (cons 62 colorVal)
      ;                  (assoc 62 entData)
      ;                  entData
      ;                )
      ;              )
      ; )
      ; 使用command方式
      (command "_-layer" "_color" colorVal layName "")

      ; (princ (strcat "\n图层 '" layName "' 可见性已切换"))
    )
    (princ (strcat "\n错误：图层 '" layName "' 不存在"))
  )
)

(defun create_circle (pt radius layer) 
  ; 画圆
  (entmakex 
    (list (cons 0 "CIRCLE") 
          (cons 10 (pt_to_list pt))
          (cons 40 radius)
          ; (cons 62 color) ; red
          (cons 8 layer)
    )
  )
)

(defun create_line (spt ept layer) 
  ; 画圆
  (entmakex 
    (list (cons 0 "LINE") 
          (cons 10 (pt_to_list spt))
          (cons 11 (pt_to_list ept))
          (cons 8 layer)
    )
  )
)

(defun set_circle_center_and_radius (ename center radius / circle_data) 
  ;; 2. 获取圆的实体数据
  (setq circle_data (entget ename))

  ;; 3. 检查是否为圆
  (if (= (cdr (assoc 0 circle_data)) "CIRCLE") 
    (progn 

      ;; 5. 修改圆心坐标（组码10）
      (if center 
        (setq circle_data (subst (cons 10 center) 
                                 (assoc 10 circle_data)
                                 circle_data
                          )
        )
      )
      ; 修改圆半径
      (if (and (not (null radius)) (> radius 0)) 
        (setq circle_data (subst (cons 40 radius) 
                                 (assoc 40 circle_data)
                                 circle_data
                          )
        )
      )

      (entmod circle_data) ;更新实体数据
      (entupd ename) ; 刷新显示
      ; (princ "\n圆已更新。")
    )
  )
)

(defun set_line_points (ename spt ept / line_data) 
  ;; 2. 获取直线的实体数据
  (setq line_data (entget ename))
  (princ "\n")
  ; (princ line_data)
  (princ (assoc 0 line_data))
  ;; 3. 检查是否为直线
  (if (= (cdr (assoc 0 line_data)) "LINE") 
    (progn 
      (if spt 
        (setq line_data (subst (cons 10 spt) (assoc 10 line_data) line_data))
      ) ; 修改起点（DXF组码10）
      (if ept 
        (setq line_data (subst (cons 11 ept) (assoc 11 line_data) line_data))
      ) ; 修改终点（DXF组码11）

      (entmod line_data) ;更新实体数据
      (entupd ename) ; 刷新显示

      T
      ; (princ "\n直线已更新。")
    )
    nil
  )
)


(defun mvs_get_new_z (pt msg mvs_last_z circle_ename / nums) 
  ; 画圆
  ; (create_circle pt 50.0 1)
  ; 移动圆心到pt
  (set_circle_center_and_radius circle_ename pt 50)

  ; 命令行交互输入z值
  (setq nums (get_two_numbers msg mvs_last_z))
  ; ; 删除圆
  ; (setq ename (ssname (ssget "L" '((0 . "CIRCLE"))) 0))
  ; (entdel ename)

  ; 返回z
  (car nums)
)

(defun mvs_deal_line (ent epsilon MVS_APP_POINT_DICT circle_ename / handle spt ept sz 
                      tz str_spt str_ept
                     ) 
  (setq handle (cdr (assoc 5 ent))) ;句柄
  (setq spt (cdr (assoc 10 ent))) ;起点坐标
  (setq ept (cdr (assoc 11 ent))) ;终点坐标

  ; 坐标转换为字符串
  (setq str_spt (vl-princ-to-string spt))
  (setq str_ept (vl-princ-to-string ept))

  ; 当前的z(初始值为起点的z值)
  (setq mvs_last_z (caddr spt))

  ; 查找起点的新z坐标
  (setq sz (get_dict_data MVS_APP_POINT_DICT str_spt))
  (if sz (setq mvs_last_z sz))
  ; 交互获取新的z值(高亮提示: 一个半径为50, 颜色为红色的圆)
  (setq sz (mvs_get_new_z spt "\n请指定起点的Z值:" mvs_last_z circle_ename))
  ; 记实到词典
  (set_dict_data MVS_APP_POINT_DICT str_spt sz)
  ; 更新当前的默认z
  (if (not (float_equal sz mvs_last_z epsilon)) (setq mvs_last_z sz))

  ; 查找终点的新z坐标
  (setq tz (get_dict_data MVS_APP_POINT_DICT str_ept))
  (if tz (setq mvs_last_z tz))

  ; 交互获取新的z值(高亮提示: 一个半径为50, 颜色为红色的圆)
  (setq tz (mvs_get_new_z ept "\n请指定终点的Z值:" mvs_last_z circle_ename))
  ; 记实到词典
  (set_dict_data MVS_APP_POINT_DICT str_ept tz)

  ; 更新当前的默认z
  (if (not (float_equal tz mvs_last_z epsilon)) (setq mvs_last_z tz))

  ; 返回2个z值
  (list sz tz)
)

(defun mvs_flush_to_file (file MVS_APP_POINT_DICT MVS_APP_ENTITY_DICT / handle ename 
                          ent spt ept str_spt str_ept sz tz count
                         ) 
  ; 获取所有标记过的直线
  (setq handleList (list_dict_data MVS_APP_ENTITY_DICT))
  ; 计数器
  (setq count 0)
  ; (princ handleList)
  (princ "\n------ 写入开始 ------ ")
  (foreach item handleList 
    (setq handle (car item)) ; 获取句柄
    (setq ename (handent handle)) ; 获取ename
    (if ename 
      (progn 
        (setq ent (entget ename))

        (setq spt (cdr (assoc 10 ent))) ;起点坐标
        (setq ept (cdr (assoc 11 ent))) ;终点坐标

        (setq str_spt (vl-princ-to-string spt))
        (setq str_ept (vl-princ-to-string ept))

        ; 查找起点和终点的新z坐标
        (setq sz (get_dict_data MVS_APP_POINT_DICT str_spt))
        (setq tz (get_dict_data MVS_APP_POINT_DICT str_ept))

        (if (and sz tz) 
          (progn 
            (setq count (+ count 1)) ; 计数器+1

            (mvs_print 
              (list "\n[" count "] " "句柄:" handle "\t起点:" str_spt " -> " sz " \t终点: " 
                    str_ept " -> " tz
              )
            )
            ; 批量写入到数据文件文件
            (mvs_file_write_line 
              (list handle 
                    (car spt)
                    (cadr spt)
                    (caddr spt)
                    (car ept)
                    (cadr ept)
                    (caddr ept)
                    sz
                    tz
              )
              file
              "\t"
            )
          )
        )
      )
    )
  )
  (princ "\n------  写入完毕 ------ ")
)

(defun get_or_create_circle_on_layer (layerName / ss) 
  ;; 创建选择集，过滤指定图层上的所有圆
  (setq ss (ssget "X" (list '(0 . "CIRCLE") (cons 8 layerName))))

  ;; 判断选择集是否存在且非空
  (if (and ss (> (sslength ss) 0)) 
    (ssname ss 0) ;; 返回第一个圆的图元名
    (create_circle (list 0 0 0) 1 layerName) ; 创建一个以(0,0,0)为中心, 半径为1的圆
  )
)

  ; 记录到词典
(defun save_line_to_dict (handle spt ept sz tz MVS_APP_POINT_DICT MVS_APP_ENTITY_DICT) 
  (set_dict_data MVS_APP_ENTITY_DICT handle handle) ; 记录到词典MVS_APP_ENTITY_DICT
  (set_dict_data 
    MVS_APP_POINT_DICT
    (vl-princ-to-string spt)
    sz
  ) ; 记录到词典MVS_APP_POINT_DICT
  (set_dict_data 
    MVS_APP_POINT_DICT
    (vl-princ-to-string ept)
    tz
  ) ; 记录到词典MVS_APP_POINT_DICT
)

(defun delete_line_from_dict (handle spt ept MVS_APP_POINT_DICT MVS_APP_ENTITY_DICT) 
  ; 删除词典记录
  (remove_dict_data MVS_APP_ENTITY_DICT handle)
  (remove_dict_data MVS_APP_POINT_DICT (vl-princ-to-string spt))
  (remove_dict_data MVS_APP_POINT_DICT (vl-princ-to-string ept))
)

(defun get_or_create_line_on_layer (layerName / ss) 
  ;; 创建选择集，过滤指定图层上的所有圆
  (setq ss (ssget "X" (list '(0 . "LINE") (cons 8 layerName))))

  ;; 判断选择集是否存在且非空
  (if (and ss (> (sslength ss) 0)) 
    (ssname ss 0) ;; 返回第一个图元名
    (create_line (list 0 0 0) (list 0 0 1) layerName) ; 创建一个起点(0,0,0), 终点(0,0,1)的直线
  )
)

;清理词典
(defun clean_mvs_app_dict (MVS_APP_POINT_DICT MVS_APP_ENTITY_DICT) 

  ; 获取所有标记过的直线
  (setq handleList (list_dict_data MVS_APP_ENTITY_DICT))
  (setq pointList (list_dict_data MVS_APP_POINT_DICT))
  (setq handle_list_to_clean '())
  (setq valid_point_list '())
  (foreach item handleList 

    (setq handle (car item)) ; 获取句柄
    (setq ename (handent handle)) ; 获取ename
    (if ename 
      (progn 
        (setq ent (entget ename))

        (setq spt (cdr (assoc 10 ent))) ;起点坐标
        (setq ept (cdr (assoc 11 ent))) ;终点坐标

        (setq str_spt (vl-princ-to-string spt))
        (setq str_ept (vl-princ-to-string ept))

        ; 查找起点和终点的新z坐标
        (setq sz (get_dict_data MVS_APP_POINT_DICT str_spt))
        (setq tz (get_dict_data MVS_APP_POINT_DICT str_ept))

        (if sz 
          (setq valid_point_list (cons (cons str_spt sz) valid_point_list))
        )
        (if tz 
          (setq valid_point_list (cons (cons str_ept tz) valid_point_list))
        )
        (if (and (not sz) (not tz)) 
          (setq handle_list_to_clean (cons handle handle_list_to_clean))
        )
      )
      (progn 
        (setq handle_list_to_clean (cons handle handle_list_to_clean))
      )
    )
  )

  ;重新创建point词典(排除非法的词典)
  (remove_dict MVS_APP_POINT_DICT)
  (if (create_dict MVS_APP_POINT_DICT) 
    (progn 
      (foreach item valid_point_list 
        (set_dict_data MVS_APP_POINT_DICT (car item) (cdr item))
      )
    )
  )
  ;清理handle
  (foreach handle handle_list_to_clean 
    (remove_dict_data MVS_APP_ENTITY_DICT handle)
  )
)

; (defun confirm (msg)
;   (initget 1 "Y N") ; 1表示必须输入Y或N，不允许空值
;   (setq ans (getkword (strcat msg " (Y/N) <N>: ")))
;   (if (not ans) (setq ans "N")) ; 处理默认值为N（当直接回车时）
;   ans
; )


(defun c:mark-zline (/ old_lwd old_cmdecho circle_ename MVS_APP_INVISIBLE_LAYER 
                     *error*
                    ) 

  ; 错误处理
  (defun *error* (msg) 
    ; (delete_layer_ents MVS_APP_INVISIBLE_LAYER) ; 删除不可见图层上的所有图形
    (set_circle_center_and_radius circle_ename (list 0 0 0) 1) ;隐藏圆
    ; (set_layer_vis MVS_APP_INVISIBLE_LAYER nil) ; 隐藏图层
    (setvar "LWDISPLAY" old_lwd) ;_恢复LWDISPLAY系统变量
    (setvar "CMDECHO" old_cmdecho) ; 恢复CMDECHO系统变量
    (princ "error:")
    (princ msg) ;_打印错误信息
    (princ)
  )

  ; 保存当前线宽可视化设置
  (setq old_lwd (getvar "LWDISPLAY"))
  (setq old_cmdecho (getvar "CMDECHO"))
  ; 显示线宽
  (setvar "LWDISPLAY" 1)
  ;关闭命令回显
  (setvar "CMDECHO" 0)
  ;禁用undo
  ; (command "_.undo" "_control" "_none") ;; 完全关闭 UNDO 功能?:ml-citation{ref="1,3" data="citationList"}

  ; 创建全局词典
  (setq MVS_APP_CONFIG_DICT "MVS_APP_CONFIG")
  (setq MVS_APP_POINT_DICT "MVS_APP_POINT")
  (setq MVS_APP_ENTITY_DICT "MVS_APP_ENTITY")
  (setq MVS_LAST_DATA_FILE_KEY "last_data_file")
  (create_dict MVS_APP_CONFIG_DICT)
  (create_dict MVS_APP_POINT_DICT)
  (create_dict MVS_APP_ENTITY_DICT)

  ; 创建隐藏图层
  (setq MVS_APP_INVISIBLE_LAYER "MVS_APP_INVISIBLE_LAYER1")
  (create_layer MVS_APP_INVISIBLE_LAYER 1 70) ; 图层颜色为红色, 线宽为0.70mm
  (setq circle_ename (get_or_create_circle_on_layer MVS_APP_INVISIBLE_LAYER)) ; 获取或创建圆
  (set_layer_vis MVS_APP_INVISIBLE_LAYER nil) ; 隐藏图层

  ; 精度 -- 用于比较浮点数是否相等
  (setq epsilon 0.000001)

  ; 计数
  (setq count 0)

  ; 连续操作直线
  (while (setq ename (select_entity "\n请选择一条直线:")) 
    (progn 
      (setq ent_type (get_entity_type ename))
      (if (eq ent_type "LINE") 
        (progn 
          ; 计数器+1
          (setq count (+ count 1))

          ; 显示图层
          (set_layer_vis MVS_APP_INVISIBLE_LAYER T)
          ; 处理直线
          (setq ent (entget ename))
          ; 返回交互得到的2个z值
          (setq two_z (mvs_deal_line 
                        ent
                        epsilon
                        MVS_APP_POINT_DICT
                        circle_ename
                      )
          )
          (setq sz (car two_z)) ; 新的起点z值
          (setq tz (cadr two_z)) ; 新的终点z值
          (setq handle (cdr (assoc 5 ent))) ;句柄
          (setq spt (cdr (assoc 10 ent))) ;起点坐标
          (setq ept (cdr (assoc 11 ent))) ;终点坐标
          (set_dict_data MVS_APP_ENTITY_DICT handle handle) ; 记录到词典
          (set_layer_vis MVS_APP_INVISIBLE_LAYER nil) ; 隐藏图层
          (mvs_print 
            (list "\n指定[" count "] " "句柄:" handle "\t起点:" spt " -> " sz " \t终点: " ept 
                  " -> " tz
            )
          )
        )
      )
    )
  )
  ; HACK 隐藏圆
  (set_circle_center_and_radius circle_ename (list 0 0 0) 1)
  (command "_.regen") ; 刷新显示

  ; (mvs_print (list "\n====== 词典" MVS_APP_POINT_DICT " ======"))
  ; (princ (list_dict_data MVS_APP_POINT_DICT))

  ; 统计词典中已处理的图元个数
  (setq total_count (count_dict MVS_APP_ENTITY_DICT))
  ;弹出提示对话框
  (alert 
    (list_to_string 
      (list "处理前: " 
            (- total_count count)
            "  处理后: "
            total_count
            "  新标记:"
            count
      )
      ""
    )
  )

  ;恢复undo
  ; (command "_.undo" "_control" "_all")
  ;恢复线宽设置
  (setvar "LWDISPLAY" old_lwd)
  ;恢复命令回显
  (setvar "CMDECHO" old_cmdecho)

  (princ)
)

(defun c:draw-zline (/ p1 p2 z1 z2 old_lwd old_cmdecho line_ename 
                     MVS_APP_INVISIBLE_LAYER *error*
                    ) 

  ; 错误处理
  (defun *error* (msg) 
    ; (delete_layer_ents MVS_APP_INVISIBLE_LAYER) ; 删除不可见图层上的所有图形
    (set_line_points line_ename (list 0 0 0) (list 0 0 1)) ;隐藏直线
    ; (set_layer_vis MVS_APP_INVISIBLE_LAYER nil) ; 隐藏图层
    (setvar "LWDISPLAY" old_lwd) ;_恢复LWDISPLAY系统变量
    (setvar "CMDECHO" old_cmdecho) ; 恢复CMDECHO系统变量
    (princ "error:")
    (princ msg) ;_打印错误信息
    (princ)
  )

  ; 保存当前线宽可视化设置
  (setq old_lwd (getvar "LWDISPLAY"))
  (setq old_cmdecho (getvar "CMDECHO"))
  ; 显示线宽
  (setvar "LWDISPLAY" 1)
  ;关闭命令回显
  (setvar "CMDECHO" 0)

  ; 创建全局词典
  (setq MVS_APP_POINT_DICT "MVS_APP_POINT")
  (setq MVS_APP_ENTITY_DICT "MVS_APP_ENTITY")
  (create_dict MVS_APP_POINT_DICT)
  (create_dict MVS_APP_ENTITY_DICT)

  ; 创建隐藏图层
  (setq MVS_APP_INVISIBLE_LAYER "MVS_APP_INVISIBLE_LAYER3")
  (create_layer MVS_APP_INVISIBLE_LAYER 1 70) ; 图层颜色为白色, 线宽为0.7mm
  (setq line_ename (get_or_create_line_on_layer MVS_APP_INVISIBLE_LAYER)) ; 获取或创建直线
  (set_layer_vis MVS_APP_INVISIBLE_LAYER nil) ; 隐藏图层

  (setq p1 (getpoint "\n请指定起点: ")) ; 获取起始点?
  (if p1 
    (progn 
      (setq z1 (getreal "\n请输入z值: ")) ; 获取z
      (if z1 
        (progn 
          (if p1 
            (progn 
              (setq continue T)
              (while continue 
                (setq p2 (getpoint p1 "\n指定下一点: "))
                (if p2 
                  (progn 
                    ;临时绘制一条线
                    (set_layer_vis MVS_APP_INVISIBLE_LAYER T) ; 显示图层
                    ; 移动直线到当前位置
                    (set_line_points 
                      line_ename
                      (list (car p1) (cadr p1) z1)
                      (list (car p2) (cadr p2) z1)
                    )

                    ; 获取z
                    (setq z2 (getreal 
                               (strcat "\n请输入z值 <默认值:" 
                                       (vl-princ-to-string z1)
                                       ">: "
                               )
                             )
                    )
                    ; 用户默认回车或者空格,则使用上一点的z值
                    (if (= z2 nil) 
                      (setq z2 z1)
                    )
                    (set_layer_vis MVS_APP_INVISIBLE_LAYER nil) ; 关闭图层

                    ; 绘制直线
                    (setq p1 (list (car p1) (cadr p1) z1))
                    (setq p2 (list (car p2) (cadr p2) z2))
                    (setq ename (create_line p1 p2 (getvar "CLAYER"))) ; 绘制当前线段

                    ; 记录到词典
                    (setq ent (entget ename)) ; 获取数据表
                    (setq handle (cdr (assoc 5 ent))) ;句柄
                    (setq spt (cdr (assoc 10 ent))) ;起点坐标
                    (setq ept (cdr (assoc 11 ent))) ;终点坐标
                    (save_line_to_dict 
                      handle
                      spt
                      ept
                      (caddr spt)
                      (caddr ept)
                      MVS_APP_POINT_DICT
                      MVS_APP_ENTITY_DICT
                    )

                    (setq p1 p2) ; 更新起点为当前终点
                    (setq z1 z2)
                  )
                  (progn 
                    (princ "\n结束绘制。")
                    (setq continue nil)
                  )
                )
              )
            )
          )
        )
        (princ "\n无效的起点z值，操作取消。")
      )
    )
    (princ "\n未指定起点，操作取消。")
  )

  ; HACK 隐藏直线和图层
  (set_line_points line_ename (list 0 0 0) (list 0 0 1))
  (set_layer_vis MVS_APP_INVISIBLE_LAYER nil)

  ;恢复线宽显示
  (setvar "LWDISPLAY" old_lwd)
  ;恢复命令回显
  (setvar "CMDECHO" old_cmdecho)

  (princ)
)


(defun c:change-zline (/ old_lwd old_cmdecho circle_ename MVS_APP_INVISIBLE_LAYER 
                       *error*
                      ) 

  ; 错误处理
  (defun *error* (msg) 
    ; (delete_layer_ents MVS_APP_INVISIBLE_LAYER) ; 删除不可见图层上的所有图形
    (set_circle_center_and_radius circle_ename (list 0 0 0) 1) ;隐藏圆
    ; (set_layer_vis MVS_APP_INVISIBLE_LAYER nil) ; 隐藏图层
    (setvar "LWDISPLAY" old_lwd) ;_恢复LWDISPLAY系统变量
    (setvar "CMDECHO" old_cmdecho) ; 恢复CMDECHO系统变量
    (princ "error:")
    (princ msg) ;_打印错误信息
    (princ)
  )

  ; 保存当前线宽可视化设置
  (setq old_lwd (getvar "LWDISPLAY"))
  (setq old_cmdecho (getvar "CMDECHO"))
  ; 显示线宽
  (setvar "LWDISPLAY" 1)
  ;关闭命令回显
  (setvar "CMDECHO" 0)
  ;禁用undo
  ; (command "_.undo" "_control" "_none") ;; 完全关闭 UNDO 功能

  ; 创建全局词典
  ; (setq MVS_APP_POINT_DICT "MVS_APP_POINT4")
  ; (create_dict MVS_APP_POINT_DICT)
  (setq MVS_APP_POINT_DICT "MVS_APP_POINT")
  (setq MVS_APP_ENTITY_DICT "MVS_APP_ENTITY")
  (create_dict MVS_APP_POINT_DICT)
  (create_dict MVS_APP_ENTITY_DICT)

  ; 创建隐藏图层
  (setq MVS_APP_INVISIBLE_LAYER "MVS_APP_INVISIBLE_LAYER4")
  (create_layer MVS_APP_INVISIBLE_LAYER 1 70) ; 图层颜色为红色, 线宽为0.70mm
  (setq circle_ename (get_or_create_circle_on_layer MVS_APP_INVISIBLE_LAYER)) ; 获取或创建圆
  (set_layer_vis MVS_APP_INVISIBLE_LAYER nil) ; 隐藏图层

  ; 精度 -- 用于比较浮点数是否相等
  (setq epsilon 0.000001)

  ; 计数
  (setq count 0)

  ; 连续操作直线
  (while (setq ename (select_entity "\n请选择一条直线:")) 
    (progn 
      (setq ent_type (get_entity_type ename))
      (if (eq ent_type "LINE") 
        (progn 
          ; 计数器+1
          (setq count (+ count 1))

          ; 显示图层
          (set_layer_vis MVS_APP_INVISIBLE_LAYER T)
          ; 处理直线
          (setq ent (entget ename))
          ; 返回交互得到的2个z值
          (setq two_z (mvs_deal_line 
                        ent
                        epsilon
                        MVS_APP_POINT_DICT
                        circle_ename
                      )
          )
          (setq sz (car two_z)) ; 新的起点z值
          (setq tz (cadr two_z)) ; 新的终点z值
          (set_layer_vis MVS_APP_INVISIBLE_LAYER nil) ; 隐藏图层

          (setq handle (cdr (assoc 5 ent))) ;句柄
          (setq spt (cdr (assoc 10 ent))) ;起点坐标
          (setq ept (cdr (assoc 11 ent))) ;终点坐标
          ; ; 删除词典记录
          ; (delete_line_from_dict handle spt ept MVS_APP_POINT_DICT
          ;                        MVS_APP_ENTITY_DICT
          ; )
          ;修改直线的z值
          (set_line_points 
            ename
            (list (car spt) (cadr spt) sz)
            (list (car ept) (cadr ept) tz)
          )

          ; 修改后更新词典记录
          (setq ent (entget ename)) ; 获取数据表
          ; (setq handle (cdr (assoc 5 ent))) ;句柄
          (setq spt (cdr (assoc 10 ent))) ;起点坐标
          (setq ept (cdr (assoc 11 ent))) ;终点坐标
          (save_line_to_dict handle spt ept sz tz MVS_APP_POINT_DICT 
                             MVS_APP_ENTITY_DICT
          )

          (mvs_print 
            (list "\n指定[" count "] " "句柄:" handle "\t起点:" spt " -> " sz " \t终点: " ept 
                  " -> " tz
            )
          )
        )
      )
    )
  )
  ; HACK 隐藏圆
  (set_circle_center_and_radius circle_ename (list 0 0 0) 1)
  (command "_.regen") ; 刷新显示

  ; 清理词典冗余数据
  (clean_mvs_app_dict MVS_APP_POINT_DICT MVS_APP_ENTITY_DICT)
  ; (mvs_print (list "\n====== 词典" MVS_APP_POINT_DICT " ======"))
  ; (princ (list_dict_data MVS_APP_POINT_DICT))

  ;恢复undo
  ; (command "_.undo" "_control" "_all")
  ;恢复线宽设置
  (setvar "LWDISPLAY" old_lwd)
  ;恢复命令回显
  (setvar "CMDECHO" old_cmdecho)

  (princ)
)

(defun c:count-zline () 
  ; 创建全局词典
  (setq MVS_APP_POINT_DICT "MVS_APP_POINT")
  (setq MVS_APP_ENTITY_DICT "MVS_APP_ENTITY")
  ; (create_dict MVS_APP_POINT_DICT)
  ; (create_dict MVS_APP_ENTITY_DICT)

  ; 获取所有标记过的直线
  (setq handleList (list_dict_data MVS_APP_ENTITY_DICT))
  ; 计数器
  (setq count 0)
  ; (princ handleList)
  (foreach item handleList 

    (setq handle (car item)) ; 获取句柄
    (setq ename (handent handle)) ; 获取ename
    (setq ent (entget ename))

    (setq spt (cdr (assoc 10 ent))) ;起点坐标
    (setq ept (cdr (assoc 11 ent))) ;终点坐标

    (setq str_spt (vl-princ-to-string spt))
    (setq str_ept (vl-princ-to-string ept))

    ; 查找起点和终点的新z坐标
    (setq sz (get_dict_data MVS_APP_POINT_DICT str_spt))
    (setq tz (get_dict_data MVS_APP_POINT_DICT str_ept))

    ; 有效的z
    (if (and sz tz) 
      (progn 
        (setq count (+ count 1)) ; 计数器+1
        (mvs_print 
          (list "\n[" count "] " "句柄:" handle "\t起点:" str_spt " -> " "z=" sz 
                " \t终点: " str_ept " -> " "z=" tz
          )
        )
      )
    )
  )
  (princ)
)

(defun c:write-zfile (/ *error*) 

  ; 错误处理
  (defun *error* (msg) 
    (princ "error:")
    (princ msg) ;_打印错误信息
    (princ)
  )

  ; 创建全局词典
  (setq MVS_APP_CONFIG_DICT "MVS_APP_CONFIG")
  (setq MVS_APP_POINT_DICT "MVS_APP_POINT")
  (setq MVS_APP_ENTITY_DICT "MVS_APP_ENTITY")
  (setq MVS_LAST_DATA_FILE_KEY "last_data_file")
  (create_dict MVS_APP_CONFIG_DICT)
  (create_dict MVS_APP_POINT_DICT)
  (create_dict MVS_APP_ENTITY_DICT)

  ; 统计词典中已处理的图元个数
  (setq total_count (count_dict MVS_APP_ENTITY_DICT))
  (if (> total_count 0) 
    (progn 
      (mvs_print (list "\n======= 批量写入到数据文件  ======"))
      ; 读取上次记录的数据文件
      (setq mvs_data_file (get_dict_data 
                            MVS_APP_CONFIG_DICT
                            MVS_LAST_DATA_FILE_KEY
                          )
      )
      (setq filename (mvs_get_file mvs_data_file))
      (if filename 
        (progn 
          ; 记录用户选择的数据文件
          (set_dict_data MVS_APP_CONFIG_DICT MVS_LAST_DATA_FILE_KEY filename)
          (mvs_print (list "\n======= 数据文件存储路径: " filename " ======"))

          (setq file (open filename "w")) ;覆盖模式(不存在则自动创建新文件)
          (if file 
            (progn 
              ; 批量写入文件
              (mvs_flush_to_file 
                file
                MVS_APP_POINT_DICT
                MVS_APP_ENTITY_DICT
              )
              ; 关闭文件
              (close file)
              (mvs_print (list "\n======= 写入文件成功  ======"))
            )
            (mvs_print (list "\n======= 写入文件失败  ======"))
          )
        )
      )
    )
  )

  (princ)
)

(defun c:read-zfile () 

  ; 创建全局词典
  (setq MVS_APP_POINT_DICT "MVS_APP_POINT")
  (setq MVS_APP_ENTITY_DICT "MVS_APP_ENTITY")
  (create_dict MVS_APP_POINT_DICT)
  (create_dict MVS_APP_ENTITY_DICT)

  ; 清理词典, 移除已被删除的直线
  (clean_mvs_app_dict MVS_APP_POINT_DICT MVS_APP_ENTITY_DICT)

  ; 选择数据文件
  (setq filename (getfiled "选择数据文件" "mvs_data.txt" ; 默认文件名
                           "txt" ; 文件扩展名过滤器（空表示全部）
                           0 ; 标志位：1=允许覆盖提示
                 )
  )
  (if filename 
    (progn 
      (setq file (open filename "r"))
      (if file 
        (progn 
          ;记录被跳过的行
          (setq ignored_line_datas '())
          (setq count 0) ; 实际的修改或创建编号
          (setq line_number 0) ; 文件行号
          (while (setq line (read-line file)) 
            (if (/= line "")  ; 过滤空行
              (progn 
                (setq line_number (+ line_number 1))
                ; 拆分字符串
                (setq data_list (string_split line "\t"))
                ; 依次取出数据
                (setq handle (nth 0 data_list))
                (setq sx (string_to_float (nth 1 data_list)))
                (setq sy (string_to_float (nth 2 data_list)))
                (setq sz (string_to_float (nth 3 data_list)))
                (setq tx (string_to_float (nth 4 data_list)))
                (setq ty (string_to_float (nth 5 data_list)))
                (setq tz (string_to_float (nth 6 data_list)))
                (setq new_sz (string_to_float (nth 7 data_list)))
                (setq new_tz (string_to_float (nth 8 data_list)))

                (if (get_dict_data MVS_APP_ENTITY_DICT handle) 
                  (progn 
                    ;词典中存在直线记录
                    ; 查找句柄对应的图元
                    (setq ename (handent handle))
                    ; 是否有效的直线图元
                    (setq is_valid_line nil)
                    (if ename 
                      ; 判断图元类型是否直线
                      (setq is_valid_line (eq (cdr (assoc 0 (entget ename))) 
                                              "LINE"
                                          )
                      )
                      (setq is_valid_line nil)
                    )
                    (if is_valid_line 
                      (progn 
                        ; (setq handle (cdr (assoc 5 ent))) ;句柄
                        ; (setq spt (cdr (assoc 10 ent))) ;起点坐标
                        ; (setq ept (cdr (assoc 11 ent))) ;终点坐标
                        ; (delete_line_from_dict handle spt ept MVS_APP_POINT_DICT
                        ;                        MVS_APP_ENTITY_DICT
                        ; )
                        ; 修改始末点坐标
                        (set_line_points 
                          ename
                          (list sx sy new_sz)
                          (list tx ty new_tz)
                        )

                        (if ename 
                          (progn 
                            (setq count (+ count 1))

                            (mvs_print 
                              (list "\n[" 
                                    count
                                    "] 修改直线 -> "
                                    "句柄:"
                                    handle
                                    "\t原起点:"
                                    spt
                                    "\t原终点:"
                                    ept
                                    "\t新起点:"
                                    (list sx sy new_sz)
                                    "\t新终点:"
                                    (list tx ty new_tz)
                              )
                            )
                            ; 获取最新的数据, 更新词典记录
                            (setq ent (entget ename)) ; 获取数据表
                            (setq handle (cdr (assoc 5 ent))) ;句柄
                            (setq spt (cdr (assoc 10 ent))) ;起点坐标
                            (setq ept (cdr (assoc 11 ent))) ;终点坐标
                            (save_line_to_dict 
                              handle
                              spt
                              ept
                              (caddr spt)
                              (caddr ept)
                              MVS_APP_POINT_DICT
                              MVS_APP_ENTITY_DICT
                            )
                          )
                        )
                      )
                      (progn 
                        ;记录要创建的直线
                        (setq ignored_line_datas (cons line ignored_line_datas))
                      )
                    )
                  )
                  (progn 
                    ;记录要创建的直线
                    (setq ignored_line_datas (cons line ignored_line_datas))
                  )
                )
              )
            )
          )
          (close file)

          ;继续处理ignored_line_datas
          (foreach line ignored_line_datas 
            ; 拆分字符串
            (setq data_list (string_split line "\t"))
            ; 依次取出数据
            (setq handle (nth 0 data_list))
            (setq sx (string_to_float (nth 1 data_list)))
            (setq sy (string_to_float (nth 2 data_list)))
            (setq sz (string_to_float (nth 3 data_list)))
            (setq tx (string_to_float (nth 4 data_list)))
            (setq ty (string_to_float (nth 5 data_list)))
            (setq tz (string_to_float (nth 6 data_list)))
            (setq new_sz (string_to_float (nth 7 data_list)))
            (setq new_tz (string_to_float (nth 8 data_list)))

            ;创建新的直线
            (setq ename (create_line 
                          (list sx sy new_sz)
                          (list tx ty new_tz)
                          (getvar "CLAYER") ;当前图层
                        )
            )
            (if ename 
              (progn 
                (setq count (+ count 1))

                ; 获取最新的数据, 更新词典记录
                (setq old_handle handle)
                (setq ent (entget ename)) ; 获取数据表
                (setq handle (cdr (assoc 5 ent))) ;句柄
                (setq spt (cdr (assoc 10 ent))) ;起点坐标
                (setq ept (cdr (assoc 11 ent))) ;终点坐标

                (mvs_print 
                  (list "\n[" 
                        count
                        "] 绘制直线 -> "
                        "起点:"
                        (list sx sy new_sz)
                        "\t终点:"
                        (list tx ty new_tz)
                        "\t原句柄:"
                        old_handle
                        "\t新句柄:"
                        handle
                  )
                )
                (save_line_to_dict 
                  handle
                  spt
                  ept
                  (caddr spt)
                  (caddr ept)
                  MVS_APP_POINT_DICT
                  MVS_APP_ENTITY_DICT
                )
              )
            )
          )

          ; 清理词典, 移除已被删除的直线
          (clean_mvs_app_dict MVS_APP_POINT_DICT MVS_APP_ENTITY_DICT)
        )
        (princ "\n====== 打开文件失败! ======")
      )
    )
  )
  (princ)
)